package org.breathe.thread.pool.common.queue;

import java.util.Collection;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 内存安全的LinkedBlockingQueue
 * 借鉴了apache的实现
 * @author: breathe
 * @createTime: 2025-04-09
 */
public class MemorySafeLinkedBlockingQueue<E> extends VariableLinkedBlockingQueue<E> {
    private static final long serialVersionUID = 3120381510234L;
    public static final int THE_16_MB = 16 * 1024 * 1024;
    private int maxFreeMemory;
    public MemorySafeLinkedBlockingQueue(final int maxFreeMemory) {
        super(Integer.MAX_VALUE);
        this.maxFreeMemory = maxFreeMemory;
    }
    public MemorySafeLinkedBlockingQueue(final int capacity, final int maxFreeMemory) {
        super(capacity);
        this.maxFreeMemory = maxFreeMemory;
    }
    public MemorySafeLinkedBlockingQueue(final Collection<? extends E> c, final int maxFreeMemory) {
        super(c);
        this.maxFreeMemory = maxFreeMemory;
    }

    /**
     * set 最大的空余空间
     */
    public void setMaxFreeMemory(final int maxFreeMemory) {
        this.maxFreeMemory = maxFreeMemory;
    }

    /**
     * 得到最大的空余空间
     */
    public int getMaxFreeMemory() {
        return maxFreeMemory;
    }

    /**
     * 判断是否有剩余内存能够继续使用
     * 如果有就是true，反之false
     */
    public boolean hashRemainedMemory() {
        if (MemoryLimitCalculator.maxAvailable() > maxFreeMemory) {
            return true;
        }
        throw new RejectedExecutionException("没有额外的内存去使用了");
    }

    @Override
    public void put(final E e) throws InterruptedException {
        if (hashRemainedMemory()) {
            super.put(e);
        }
    }
    @Override
    public boolean offer(final E e, final long timeout, final TimeUnit unit) throws InterruptedException {
        return hashRemainedMemory() && super.offer(e, timeout, unit);
    }
    @Override
    public boolean offer(final E e) {
        return hashRemainedMemory() && super.offer(e);
    }
}
